package Day_0226.StrategyPattern;

/**
 * @author zxc
 * @date 2023/02/27 10:28
 **/
public class StrategyPattern {
    public static void main(String[] args) {
        /**
         * 谈一谈对于 策略模式的理解
         * ===》
         * 1.策略模式的概念
         * ===》
         * （1）定义了一系列的算法 或 逻辑 或 相同意义的操作，并将每一个算法、逻辑、操作封装起来，而且使它们还可以相互替换。
         * （其实策略模式Java中用的非常非常广泛）
         * （2）主要是为了 简化 if…else 所带来的复杂和难以维护。
         *
         * 2.策略模式应用场景
         * ===》
         * 策略模式的用意是针对一组算法或逻辑，将每一个算法或逻辑封装到具有共同接口的独立的类中，从而使得它们之间可以相互替换。
         * （1）例如：我要做一个不同会员打折力度不同的三种策略，初级会员，中级会员，高级会员（三种不同的计算）。
         * （2）例如：我要一个支付模块，我要有微信支付、支付宝支付、银联支付等
         *
         * 3.策略模式的优点和缺点
         * 1）优点 ：
         * （1）算法可以自由切换。
         * （2）避免使用多重条件判断。
         * （3）扩展性非常良好。
         * 2）缺点：
         * （1）策略类会增多。
         * （2）所有策略类都需要对外暴露。
         *
         *
         * ===》
         * 总结 ：
         * （1）针对一组算法或逻辑，将每一个算法或逻辑封装到具有共同接口的独立的类中;
         * （2）首先，定义一个公共接口，定义抽象方法（所有继承该接口的类都需要实现所定义的抽象方法;）
         * （3）定义上下文维护策略，创建公共接口对象，通过传入不同的公共接口实现类，来获取不同公共接口实现类的功能;
         * （4）使用时，调用所定义的上下文维护策略，通过改变所传入参数，来获取该策略模式中的不同功能;
         *
         */
    }
}
//策略模式 定义抽象方法 所有支持公共接口
abstract class PayStrategy {
    // 支付逻辑方法
    abstract void algorithmInterface();
}
// 具体实现类---微信支付
class PayStrategyA extends PayStrategy {
    void algorithmInterface() {
        System.out.println("微信支付");
    }
}
// 具体实现类 --- 支付宝支付
class PayStrategyB extends PayStrategy {
    void algorithmInterface() {
        System.out.println("支付宝支付");
    }
}
// 具体实现类 --- 银联支付
class PayStrategyC extends PayStrategy {
    void algorithmInterface() {
        System.out.println("银联支付");
    }
}
// 定义上下文维护算法策略;
// 针对一组算法或逻辑，将每一个算法或逻辑封装到 具有共同接口的独立类中
class Context {
    // 接口对象
    PayStrategy strategy;
    // 构造方法中，需要传入该接口的具体实现类实例
    public Context(PayStrategy strategy) {
        this.strategy = strategy;
    }
    // 调用 所传入的具体实现类实例的方法
    public void algorithmInterface() {
        strategy.algorithmInterface();
    }
}
class ClientTestStrategy {
    public static void main(String[] args) {
        Context context;
        //使用支付逻辑A
        context = new Context(new PayStrategyA());
        context.algorithmInterface();
        //使用支付逻辑B
        context = new Context(new PayStrategyB());
        context.algorithmInterface();
        //使用支付逻辑C
        context = new Context(new PayStrategyC());
        context.algorithmInterface();
    }
}